package com.lagou.handler;

import com.lagou.response.RpcResponse;
import com.lagou.request.RpcRequest;
import com.lagou.utils.SpringContextUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.springframework.beans.BeanUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // msg: 是否是RpcRequest对象
        if (msg != null && RpcRequest.class.isInstance(msg)) {
            RpcResponse rpcResponse = new RpcResponse();

            RpcRequest rpcRequest = (RpcRequest) msg;
            String className = rpcRequest.getClassName();
            Object bean = SpringContextUtils.getBean(className);
            if (bean == null) {
                rpcResponse.setCode(RpcResponse.OK);
                rpcResponse.setData("className not exist");
                ctx.writeAndFlush(rpcResponse);
                return;
            }

            Method method = BeanUtils.findDeclaredMethod(bean.getClass(), rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
            if (method == null) {
                rpcResponse.setCode(RpcResponse.OK);
                rpcResponse.setData("method not exist");
                ctx.writeAndFlush(rpcResponse);
                return;
            }

            try {
                Object result = method.invoke(bean, rpcRequest.getParameters());
                rpcResponse.setCode(0);
                rpcResponse.setData(result);
                ctx.writeAndFlush(rpcResponse);
            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                rpcResponse.setCode(RpcResponse.ERROR);
                rpcResponse.setData("remote call error");
                ctx.writeAndFlush(rpcResponse);
            }
        }
    }
}
